package top.lyjwn.todo.common.utils;

import com.alibaba.fastjson2.JSON;
import com.jayway.jsonpath.Filter;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;

import java.util.List;
import java.util.Map;

import static com.jayway.jsonpath.Criteria.where;

public class JsonUtil {

    public static String toJson(Object obj) {
        return JSON.toJSONString(obj);
    }

    public static <T> T toObj(String json, Class<T> clazz) {
        return JSON.parseObject(json, clazz);
    }

    public static <T> List<T> toList(String json, Class<T> clazz) {
        return JSON.parseArray(json, clazz);
    }

    public static void main(String[] args) {
        String json = "{\"users\": [{\"name\": \"John\", \"age\": 30}, {\"name\": \"Jane\", \"age\": 25}]}";
        ReadContext ctx = JsonPath.parse(json);
        // 使用JsonPath表达式查询数组数据：
        // 使用JsonPath表达式$.users[*].name和$.users[*].age分别从JSON数组中提取了所有用户的姓名和年龄。
        // 使用了通配符[*]来表示所有数组元素
        List<String> names = ctx.read( "$.users[*].name");
        System.out.println(names); // ["John","Jane"]

        String name = ctx.read( "$.users[0].name");
        System.out.println(name); // John

        // 使用JsonPath表达式$.users[0] 来查询数组第一个元素
        User user = ctx.read( "$.users[0]",User.class);
        System.out.println(JsonUtil.toJson(user)); // {name=John, age=30}
        //
        List<Map<String, Object>> users = ctx.read( "$.users[*]",where("name").is("John"));
        System.out.println(JsonUtil.toJson(users)); // {name=John, age=30}
        // 迭代数组：
        // 可以使用JsonPath表达式迭代JSON数组并执行其他操作。
        // 例如，以下示例使用JsonPath表达式迭代JSON数组并计算所有用户的平均年龄：
        List<Integer> ages = ctx.read( "$.users[*].age");
        double averageAge = ages.stream().mapToInt(Integer::intValue).average().orElse(0.0);
        System.out.println(averageAge); // 27.5
    }

    public static class User
    {
        private String name;
        private String age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getAge() {
            return age;
        }

        public void setAge(String age) {
            this.age = age;
        }
    }
}
